package com.innovation.ic.b1b.framework.manager;

import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;

@Slf4j
public class ThreadPoolManager {

    private volatile static ThreadPoolTaskExecutor threadPoolTaskExecutor;

    public ThreadPoolManager(int corePoolSize, int maximumPoolSize, int keepAliveTime,
                             int queueSize, String threadNamePrefix) {
        if (null == threadPoolTaskExecutor) {
            synchronized (ThreadPoolManager.class) {
                if (null == threadPoolTaskExecutor) {
                    threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
                    threadPoolTaskExecutor.setCorePoolSize(corePoolSize);
                    threadPoolTaskExecutor.setMaxPoolSize(maximumPoolSize);
                    threadPoolTaskExecutor.setKeepAliveSeconds(keepAliveTime);
                    threadPoolTaskExecutor.setQueueCapacity(queueSize);
                    if (null != threadNamePrefix){
                        threadPoolTaskExecutor.setThreadNamePrefix(threadNamePrefix);
                    }

                    threadPoolTaskExecutor.setRejectedExecutionHandler(new RejectedExecutionHandler() {
                        @Override
                        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                            log.error("触发拒绝策略, 当前活跃线程数{} , 队列长度{} ", executor.getActiveCount(), executor.getQueue().size());
                        }
                    });

                    threadPoolTaskExecutor.initialize();
                    log.info("--初始化全局线程池-- corePoolSize {}, maximumPoolSize {}, keepAliveTime {}, " +
                                    "workQueue {}, threadNamePrefix {}", corePoolSize, maximumPoolSize, keepAliveTime,
                            queueSize, threadNamePrefix);
                }
            }
        }
    }

    public ThreadPoolTaskExecutor getThreadPoolTaskExecutor(){
        return threadPoolTaskExecutor;
    }

    public void execute(Runnable command) {
        threadPoolTaskExecutor.execute(command);
    }

    public Future<Object> submit(Callable<Object> callable, String none) {
        return threadPoolTaskExecutor.submit(callable);
    }

    public Future<String> submit(Callable<String> callable) {
        return threadPoolTaskExecutor.submit(callable);
    }
}
